//
//  FileReceive.m
//  FileReceive
//
//  Created by cr on 2021/3/24.
//

#import <Foundation/Foundation.h>
#import <React/RCTEventEmitter.h>
#import <AliyunOSSiOS/AliyunOSSiOS.h>

@interface OSSModule : RCTEventEmitter<RCTBridgeModule>
@property (nonatomic, strong) OSSClient *defaultClient;
@property (nonatomic, strong) OSSPutObjectRequest *normalUploadRequest;
@property (nonatomic, copy) NSString *bucketName;
@property (nonatomic, copy) NSString *callbackUrl;
@end

@implementation OSSModule

RCT_EXPORT_MODULE()

+(BOOL)requiresMainQueueSetup
{
    return YES;
}


RCT_EXPORT_METHOD(initOSSConfig
                  : (NSDictionary *)dict){
    NSString *stsurl =  [dict valueForKey:@"stsurl"];
    NSString *endpointurl = [dict valueForKey:@"endpointurl"];
    self.bucketName = [dict valueForKey:@"bucket"];
    self.callbackUrl = [dict valueForKey:@"callbackurl"];
    id<OSSCredentialProvider> credentialProvider = [[OSSAuthCredentialProvider alloc] initWithAuthServerUrl:stsurl];
    OSSClientConfiguration *cfg = [[OSSClientConfiguration alloc] init];
    cfg.maxRetryCount = 3;
    cfg.timeoutIntervalForRequest = 15;
    cfg.isHttpdnsEnable = NO;
    cfg.crc64Verifiable = YES;
    _defaultClient = [[OSSClient alloc] initWithEndpoint:endpointurl credentialProvider:credentialProvider clientConfiguration:cfg];
    
}

RCT_EXPORT_METHOD(uploadFile
                 : (NSDictionary *)dict){
    NSString *filename =  [dict valueForKey:@"filename"];
    NSString *path =  [dict valueForKey:@"path"];
    [self asyncPutImage:filename localFilePath:path success:^(id result) {
            [self sendEventWithName:@"OSSModule"
                               body:@{@"code":@(200),
                                      @"filekey":filename,
                                      }];

    } failure:^(NSError * error) {
    }];
    
}
RCT_EXPORT_METHOD(stopUpload){
    if(_normalUploadRequest)
    {
        [_normalUploadRequest cancel];
    }
}
- (NSArray<NSString *> *)supportedEvents {
    return @[@"OSSModule"];
}

- (void)asyncPutImage:(NSString *)objectKey localFilePath:(NSString *)filePath success:(void (^)(id _Nullable))success failure:(void (^)(NSError * _Nonnull))failure {
    if (![objectKey oss_isNotEmpty]) {
        NSError *error = [NSError errorWithDomain:NSInvalidArgumentException code:0 userInfo:@{NSLocalizedDescriptionKey: @"objectKey should not be nil"}];
        failure(error);
        return;
    }
    _normalUploadRequest = [OSSPutObjectRequest new];
    _normalUploadRequest.bucketName = self->_bucketName;
    _normalUploadRequest.objectKey = objectKey;
    __weak typeof(self) weakSelf = self;
    _normalUploadRequest.uploadProgress = ^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) {
        typeof(weakSelf) __strong strongSelf = weakSelf;
        int p = (int)((totalBytesSent*100)/totalBytesExpectedToSend);
        [strongSelf sendEventWithName:@"OSSModule"
                           body:@{@"code":@(201),
                                  @"filekey":objectKey,
                                  @"progress":@(p)
                                  }];
      
    };
    _normalUploadRequest.uploadingFileURL = [NSURL fileURLWithPath:filePath];
    _normalUploadRequest.isAuthenticationRequired = YES;
    _normalUploadRequest.callbackParam = @{
                                           @"callbackUrl": self->_callbackUrl,
                                           // callbackBody可自定义传入的信息
                                           @"callbackBody": @"filename=${objectKey}"
                                           };
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        OSSTask * task = [self->_defaultClient putObject:self->_normalUploadRequest];
        [task continueWithBlock:^id(OSSTask *task) {
            if (task.error) {
                failure(task.error);
            } else {
                  success(task.result);
            }
            return nil;
            
//            dispatch_async(dispatch_get_main_queue(), ^{
//                if (task.error) {
//                    failure(task.error);
//                } else {
//                    success(task.result);
//                }
//            });
//
//            return nil;
        }];
    });
}
@end
